/*
 * Project: a2
 * Copyright (C) 2008 ralfoide gmail com,
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.alfray.a2.gameplay;



/**
 * Current state of the game.
 * <p/>
 * This must NEVER reference android objects that depend on the current
 * activity (e.g. activity, context, resources, etc.). Typically this
 * is all that needs to be preserved or serialized to recreate a full
 * game in the exact same state.
 * <p/>
 * Design contract: This is a "lightweight" structure. Fields are public
 * and accessible directly for read (there are not getters); however users
 * should use the setters to modify a field.
 * <p/>
 * Conventions: Bx/By mean board/cell coordinates. Px/Py mean pixel coordinates.
 */
public class GameState {


    public static final int[] MAGENTA = { 0x10000, 0x00000, 0x10000, 0x10000 };
    public static final int[] CYAN    = { 0x00000, 0x10000, 0x10000, 0x10000 };
    public static final int[] BLUE    = { 0x00000, 0x00000, 0x10000, 0x10000 };
    public static final int[] GREEN   = { 0x00000, 0x10000, 0x00000, 0x10000 };
    public static final int[] YELLOW  = { 0x10000, 0x10000, 0x00000, 0x10000 };
    public static final int[] ORANGE  = { 0x10000, 0x08000, 0x00000, 0x10000 };
    public static final int[] RED     = { 0x10000, 0x00000, 0x00000, 0x10000 };
    public static final int[] WHITE   = { 0x10000, 0x10000, 0x10000, 0x10000 };

    public static final int[][] BASE_COLORS = {
        MAGENTA, CYAN, BLUE, GREEN, YELLOW, ORANGE, RED, WHITE
    };

    /** Screen angle 0 degrees */
    public final static int DIR_DOWN = 0;
    /** Screen angle 90 degrees */
    public final static int DIR_RIGHT = 1;
    /** Screen angle 180 degrees */
    public final static int DIR_UP = 2;
    /** Screen angle 270 degrees */
    public final static int DIR_LEFT = 3;


    /** Board width */
    public final int mBoardBx = 6;
    /** Board height */
    public final int mBoardBy = 7;
    /**
     * Returns the board Cell array.
     * Cells are organized per row, i.e. index = x + y * width.
     * <p/>
     * Loops are for(j) { for(i) k++ }
     */
    public final Cell[] mBoard;

    public int mSpriteBgDefault = 0;
    public int mSpriteBgSelected = 1;
    public int mSpriteMain = 2;

    public int mSelectionBx = -1;
    public int mSelectionBy = -1;
    public int mSelectionN = -1;

    public int mMoves;
    public int mScore;

    /** Screen orientation angle in degrees. 0=down, 90=right, etc. */
    public int mScreenAngle;
    /** Screen orientation direction. One of {@link #DIR_DOWN}, etc. */
    public int mScreenDir = DIR_DOWN;
    /** Name of the visual theme. */
    public String mVisualTheme;

    public GameState() {
        int n = mBoardBx * mBoardBy;
        mBoard = new Cell[n];
        n = 0;
        for (int j = 0; j < mBoardBy; j++) {
            for (int i = 0; i < mBoardBx; i++) {
                mBoard[n++] = new Cell(i, j);
            }
        }
    }

    /**
     * Returns cell at given indexes or null if cell is out of bounds.
     */
    public Cell getCell(int bx, int by) {
        int k = bx + by * mBoardBx;
        if (k < 0 || k >= mBoard.length) return null;
        return mBoard[k];
    }

    /**
     * Returns the current selected cell.
     * @returns null if mSelectionN is negative.
     * @throws ArrayIndexOutOfBoundsException if bx or by are too big.
     */
    public Cell getSelectedCell() {
        if (mSelectionN < 0) return null;
        return mBoard[mSelectionN];
    }

    public void setSpriteBgDefault(int spriteBgDefault) {
        mSpriteBgDefault = spriteBgDefault;
    }

    public void setSpriteBgSelected(int spriteBgSelected) {
        mSpriteBgSelected = spriteBgSelected;
    }

    public void setSpriteMain(int spriteMain) {
        mSpriteMain = spriteMain;
    }

    public void setSelection(int bx, int by) {
        mSelectionBx = bx;
        mSelectionBy = by;
        mSelectionN  = bx + by * mBoardBx;
    }

    public void setVisualTheme(String visualTheme) {
        mVisualTheme = visualTheme;
    }

    /**
     * Sets screen orientation information.
     *
     * @param angle Screen orientation angle in degrees. 0=down, 90=right, etc.
     * @param direction Screen orientation direction. One of {@link #DIR_DOWN}, etc.
     */
    public void setScreenAngle(int angle, int direction) {
        mScreenAngle = angle;
        mScreenDir = direction;
    }

    public void incMoves(int deltaMoves) {
        mMoves += deltaMoves;
    }

    public void incScore(int deltaScores) {
        mScore += deltaScores;
    }

    //----

    // TODO: serialize, deserialize
}
